<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <title>扫一扫</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <link rel="shortcut icon" type="image/x-icon" href="../favicon.ico"/>
    <link rel="stylesheet" href="../layui-admin/layui/css/layui.css" media="all">
    <link rel="stylesheet" href="../weui/weui.min.css" media="all">
    <style>
        #scan-video {
            display: none;
            background: black;
            width: 100%;
            height: 100%;
            overflow: hidden;
            position: absolute;
            z-index: 99999999;
        }

        #scan-close {
            position: absolute;
            top: 10px;
            left: 10px;
            font-size: 30px;
            text-decoration: none;
            color: white;
        }

        #scan-image {
            position: absolute;
            bottom: 10px;
            left: 10px;
            font-size: 30px;
            text-decoration: none;
            color: white;
        }

        #scan-file {
            display: none;
        }

        #scan-code {
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            position: absolute;
        }

        body, div, span {
            display: block;
            margin: 0;
            padding: 0;
        }

        video {
            display: none;
            width: 100%;
            height: 100%;
            position: relative;
        }

        canvas {
            width: 100%;
            height: 100%;
            position: relative;
        }
    </style>
</head>
<body>
<div id="scan-video">
    <video id="video"></video>
    <canvas id="canvas"></canvas>
    <span id="scan-close" class="layui-icon layui-icon-left"></span>
    <span id="scan-image" class="layui-icon layui-icon-picture"></span>
    <input id="scan-file" type="file" accept=".jpg,.png"/>
</div>
<div id="scan-code">
    <a class="weui-btn weui-btn_primary">扫一扫</a>
</div>
<script src="js/jsQR.js"></script>
<script src="../weui/zepto.min.js"></script>
<script src="../weui/weui.min.js"></script>
<script type="text/javascript">
    let anim;
    const video = document.getElementById('video');
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext("2d");
    $('#scan-code').on('click', () => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        $('#scan-video').show();
        try {
            navigator.mediaDevices.getUserMedia({
                video: {facingMode: 'environment'}//后置摄像头
            }).then((stream) => {
                video.srcObject = stream;
                video.setAttribute('playsinline', true); //阻止IOS视频全屏
                video.play();
                anim = requestAnimationFrame(tick);
            }).catch((err) => {
                alert("异常：" + err);
            });
        } catch (err) {
            alert("异常：" + err);
        }
    });
    $('#scan-close').on('click', () => {
        stop();
    });
    $('#scan-image').on('click', function () {
        $("#scan-file").click();
    });
    $("#scan-file").on("change", function () {
        const that = this;
        const files = this.files || [];
        if (files.length === 0) return;
        const reader = new FileReader();
        reader.readAsDataURL(files[0]);
        reader.onload = function (ev) {
            const image = new Image();
            image.src = ev.target.result;
            image.onload = function () {
                const qr = scan(this, this.width, this.height);
                if (qr && qr.data) {
                    alert("结果：" + qr.data);
                }
                stop();
            };
            that.value = null;
        };
    });

    function scan(image, width, height) {
        canvas.width = width;
        canvas.height = height;
        ctx.drawImage(image, 0, 0, width, height);
        const img = ctx.getImageData(0, 0, width, height);
        console.log(img);
        return jsQR(img.data, img.width, img.height, {inversionAttempts: "dontInvert"});
    }

    function tick() {
        if (video.readyState === video.HAVE_ENOUGH_DATA) {
            const qr = scan(video, video.videoWidth, video.videoHeight);
            if (qr && qr.data) {
                alert("结果：" + qr.data);
                stop();
                return;
            }
        }
        anim = requestAnimationFrame(tick);
    }

    function stop() {
        cancelAnimationFrame(anim);
        $('#scan-video').hide();
        video.pause();
    }
</script>
</body>
</html>
